<template>
  <el-space direction="vertical" alignment="flex-start" :size="24" style="margin-left:290px">
    <!-- 级联控件 -->
    <el-cascader
        v-model="selected"
        :options="cascaderOpts"
        :props="{ multiple:true, emitPath:true }"
        clearable
        placeholder="点击选择场景 / 设施 / 材质 / 朝向（支持多选）"
        style="width:420px"
    />

    <div class="download-actions">
      <el-button @click="reset" class="btn-reset">重置筛选</el-button>
      <el-button type="primary" @click="downloadAll" class="btn-download">
        确认下载 ({{ filtered.length }})
      </el-button>
      <el-button type="info" plain style="margin-left:20px" @click="load">重新拉取</el-button>
      <el-button type="success" plain style="margin-left:20px"
                 @click="downloadBatch" :disabled="!filtered.length">
        批量下载 ZIP
      </el-button>
    </div>

    <div style="margin-top:16px">
      <el-select
          v-model="selectedTag"
          placeholder="选择标签批量下载"
          filterable clearable
          style="width:220px"
      >
        <el-option
            v-for="t in tagOptions"
            :key="t.id"
            :label="t.tag_name"
            :value="t.tag_name"
        />
      </el-select>

      <el-button
          type="success"
          :loading="loadingTag"
          :disabled="!selectedTag"
          style="margin-left:12px"
          @click="downloadTagZip"
      >
        标签 ZIP 下载
      </el-button>

      <el-button
          type="info" plain
          style="margin-left:12px"
          @click="handleRefreshTags"
      >
        刷新标签
      </el-button>
    </div>

    <el-row :gutter="20" style="margin-top:40px;width:960px">
      <el-col v-for="f in filtered" :key="f.id" :span="6">
        <el-card shadow="hover">
          <img :src="f.file_url" style="width:100%;height:120px;object-fit:cover;border-radius:4px">
          <div style="margin-top:6px;font-size:12px">{{ f.file_name }}</div>
          <el-button type="primary" size="small" style="margin-top:6px;width:100%"
                     @click="()=>window.open(`${API_BASE}/assets/${f.id}/download`,'_blank')">
            下载
          </el-button>
        </el-card>
      </el-col>
    </el-row>
  </el-space>
</template>

<script setup>
import {ref, computed, onMounted} from 'vue'
import {ElMessage} from 'element-plus'

/* ======================================================== 公共工具 ==================================================================== */
const API_BASE = '/api/v1'
const TOKEN = localStorage.getItem('token')

async function api(url, opt = {}) {
  return fetch(`${API_BASE}${url}`, {
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${TOKEN}`,
      ...(opt.headers || {})
    },
    ...opt
  }).then(r => r.json())
}

/* ---------------- util：assets → 级联树 ---------------- */
function buildTreeFromAssets(files) {
  const root = {}
  files.forEach(({task_context, file}) => {
    let cur = root
    task_context.forEach((seg, i) => {
      if (!seg) return                         // 忽略空段
      cur[seg] = cur[seg] || {_c: {}, _files: []}
      if (i === task_context.length - 1) cur[seg]._files.push(file)
      cur = cur[seg]._c
    })
  })
  const dfs = node => Object.entries(node).map(([label, obj]) => ({
    label, value: label,
    children: dfs(obj._c),
    files: obj._files
  }))
  return dfs(root)
}

const cascaderOpts = ref([])
const selected = ref([])
const allFiles = ref([])

/* ============= 批量下载 Tag 模式相关 ============= */
const tagOptions = ref([])
const selectedTag = ref(null)
const loadingTag = ref(false)

/* ============= 批量下载 ============= */

/* 拉取标签列表 */
const loadTags = async () => {
  try {
    const {code, data, message} = await api('/tags')
    if (code !== 0) throw new Error(message || '接口错误')
    tagOptions.value = (data || []).filter(t => t.is_active)
    selectedTag.value = null
  } catch (e) {
    ElMessage.error('拉取标签失败：' + e.message)
  }
}

/* ---------- 刷新标签：带提示 ---------- */
const handleRefreshTags = async () => {
  ElMessage.info('正在刷新标签 …')
  await loadTags()                              // 调用原函数
  ElMessage.success('标签列表已刷新')
}

/* 按标签下载 ZIP */
const downloadTagZip = async () => {
  if (!selectedTag.value) {
    ElMessage.warning('请先选择标签')
    return
  }
  loadingTag.value = true
  try {
    const res = await fetch(`${API_BASE}/assets/tag_download`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: 'Bearer ' + TOKEN
      },
      body: JSON.stringify({tag: selectedTag.value})
    })

    const ctype = res.headers.get('content-type') || ''
    if (ctype.includes('application/zip')) {
      const blob = await res.blob()
      const fname = `${selectedTag.value}_${Date.now()}.zip`
      // 这里需要引入 FileSaver.js 或使用原生方法
      const url = window.URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = url
      a.download = fname
      a.click()
      window.URL.revokeObjectURL(url)
    } else {
      const {code, data, message} = await res.json()
      if (code !== 0 || !data?.url) throw new Error(message || '后端未返回文件')
      window.open(data.url, '_blank')
    }
    ElMessage.success('开始下载 ZIP')
  } catch (e) {
    ElMessage.error('下载失败：' + e.message)
  } finally {
    loadingTag.value = false
  }
}

/* ============= 筛选 ============= */
const load = async () => {
  const {data} = await api('/assets')
  console.log(data)
  const flat = []
  Object.values(data || {}).flat().forEach(f => {
    flat.push({task_context: f.task_context, file: f})
  })
  allFiles.value = flat
  cascaderOpts.value = buildTreeFromAssets(flat)
  selected.value = []
  ElMessage.success('素材列表已更新')
}

const filtered = computed(() => {
  if (!selected.value.length) return []
  return allFiles.value.filter(({task_context}) =>
      selected.value.some(path => path.every((seg, i) => task_context[i] === seg))
  ).map(o => o.file)
})

const reset = () => {
  selected.value = []
}

const downloadOne = async (file) => {
  try {
    const res = await fetch(`${API_BASE}/assets/${file.id}/download`, {
      headers: {Authorization: 'Bearer ' + TOKEN}
    })
    if (!res.ok) throw new Error('网络错误 ' + res.status)
    const blob = await res.blob()

    /* 生成本地 URL 触发下载 */
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = file.file_name            // 保留原文件名
    document.body.appendChild(a)
    a.click()
    a.remove()
    URL.revokeObjectURL(url)
  } catch (e) {
    ElMessage.error('下载失败：' + e.message)
  }
}

const downloadAll = () => {
  if (!filtered.value.length) {
    ElMessage.warning('请先勾选标签')
    return
  }
  filtered.value.forEach(downloadOne)
}

const downloadBatch = async () => {
  if (!filtered.value.length) {
    ElMessage.warning('请先勾选标签')
    return
  }
  try {
    /* ① 取所有 id */
    const ids = filtered.value.map(f => f.id)

    /* ② POST 到批量下载接口 */
    const res = await fetch(`${API_BASE}/assets/batch_download`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: 'Bearer ' + TOKEN
      },
      body: JSON.stringify({submission_ids: ids})
    })

    /* ③ 两种返回兼容 */
    const ctype = res.headers.get('content-type') || ''
    if (ctype.includes('application/zip')) {
      /* 直接是 zip 流 */
      const blob = await res.blob()
      const fname = `素材批量_${new Date().toISOString().slice(0, 10)}.zip`
      // 这里需要引入 FileSaver.js 或使用原生方法
      const url = window.URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = url
      a.download = fname
      a.click()
      window.URL.revokeObjectURL(url)
    } else {
      /* 假设是 JSON，取 url */
      const {code, data, message} = await res.json()
      if (code !== 0 || !data?.url) throw new Error(message || '获取下载链接失败')
      window.open(data.url, '_blank')
    }

    ElMessage.success('批量下载已开始')
  } catch (e) {
    ElMessage.error('批量下载失败：' + e.message)
  }
}

onMounted(() => {
  load()        // 级联-场景文件
  loadTags()    // 标签列表
})

// 暴露方法给父组件
defineExpose({
  load,
  loadTags
})
</script>

<style scoped>
/* 从 control.css 中提取相关样式 */
.filter-row {
  display: flex;
  align-items: center;
  gap: 24px; /* 复选框之间间距 */
  margin-left: 290px; /* 与前两页保持对齐 */
  margin-bottom: 40px;
}

.filter-label {
  width: 90px; /* 固定列宽便于对齐 */
  text-align: right; /* ★ 右对齐 */
  color: #333;
  font-size: 16px;
  user-select: none;
}

.filter-row label {
  font-size: 16px;
  white-space: nowrap;
}

/* ===== 底部按钮（重置 / 下载） ===== */
.download-actions {
  margin-top: 60px;
  text-align: center;
}

/* ---------- 勾选框  ---------- */
input[type="checkbox"].cb-lg {
  transform: scale(1.3); /* 放大 1.3 倍 */
  transform-origin: left center; /* 避免放大后偏移 */
  accent-color: #1890ff; /* 选中时蓝色，未选中也有蓝边框 */
  margin-right: 6px; /* 放大后文字与框的间距 */
}

.btn-reset {
  width: 140px; /* 宽度可按需调整 */
  height: 40px;
  background: #fefdfd;
  color: black;
  border: 1px solid #1890ff !important;
  border-radius: 4px;
  font-size: 18px; /* 字体大小 */
  font-weight: 400; /* 字体略加粗（可选） */
  margin-right: 20px;
}

/* 下载 */
.btn-download {
  width: 240px; /* 如图较宽，可再缩放 */
  height: 40px;
  background: #1890ff;
  color: #fff;
  border: 1px solid #1890ff;
  border-radius: 4px;
  font-size: 18px; /* 字体大小 */
  font-weight: 400; /* 字体略加粗（可选） */
}

.btn-reset:hover,
.btn-download:hover {
  opacity: .85;
}
</style>